<?php

namespace app\common\model;

use think\Db;
use think\Model;

/**
 * 会员模型
 */
class User extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    // 追加属性
    protected $append = [
        'url',
        'id_text',
        'mobile_text'
        // 'qrcode_url',
    ];

    /**
     * 获取个人URL
     * @param string $value
     * @param array  $data
     * @return string
     */
    public function getUrlAttr($value, $data)
    {
        return "/u/" . $data['id'];
    }

    protected function getIdcardAttr($value)
    {
        return base64_encode($value);
    }
    public function getIdTextAttr($value, $data)
    {
        return intval($data['id'])+config('virtual_userid');
    }
    public function getMobileTextAttr($value, $data)
    {
        return substr($data['mobile'], 0, 3) . '****' . substr($data['mobile'], -4);
    }

    /**
     * 获取会员的组别
     */
    public function getGroupAttr($value, $data)
    {
        return UserGroup::get($data['group_id']);
    }

    /**
     * 获取会员的二维码
     */
    // public function getQrcodeUrlAttr($value, $data)
    // {
    //     return config('upload_domain').$data['qrcode'];
    // }

    /**
     * 获取头像
     * @param string $value
     * @param array  $data
     * @return string
     */
    public function getAvatarAttr($value, $data)
    {
        // if (!$value) {
        //     //如果不需要启用首字母头像，请使用
        //     //$value = '/assets/img/avatar.png';
        //     $value = letter_avatar($data['nickname']);
        // }
        if (!strpos($data['avatar'], '://')) {
            $data['avatar'] = config('oss_domain').$data['avatar'];
        }
        return $data['avatar'];
    }

    /**
     * 获取验证字段数组值
     * @param string $value
     * @param array  $data
     * @return  object
     */
    public function getVerificationAttr($value, $data)
    {
        $value = array_filter((array)json_decode($value, true));
        $value = array_merge(['email' => 0, 'mobile' => 0], $value);
        return (object)$value;
    }

    /**
     * 设置验证字段
     * @param mixed $value
     * @return string
     */
    public function setVerificationAttr($value)
    {
        $value = is_object($value) || is_array($value) ? json_encode($value) : $value;
        return $value;
    }

    /**
     * 变更会员余额
     * @param int    $money   余额
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     * @param string $tran_no 编号
     * @param string $is_freeze    是否是冻结行为
     */
    public static function money($money, $user_id, $memo, $tran_no, $is_freeze = 0, $log_status = 1)
    {
        $arr = ['商家支付活动'=>2,'订单审核通过'=>6,'财务修改账单金额'=>7,'提现' =>3,'提现通过'=>8,'提现驳回'=>9,'商家结算'=>10,'冻结返还'=>4,'充值'=>1,'经纪人收益'=>12,'异常订单收回佣金'=>13];
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $money != 0) {
                if ($is_freeze) {
                    if ($money>0) { //金额减少，冻结增加
                        $before = $user->money;
                        $after = function_exists('bcsub') ? bcsub($user->money, $money, 2) : $user->money - $money;
                        $before_freeze = $user->freeze_money;
                        $after_freeze = function_exists('bcadd') ? bcadd($user->freeze_money, $money, 2) : round($user->freeze_money + $money,2);
                        //更新会员信息
                        $res = $user->save(['freeze_money' => $after_freeze,'money'=>$after]);
                        //写入日志
                        UserMoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before_freeze_money' => $before_freeze, 'after_freeze_money' => $after_freeze, 'memo' => $memo,'log_type'=>$arr[$memo],'log_status'=>$log_status,'tran_no'=>$tran_no]);
                        UserMoneyLog::create(['user_id' => $user_id, 'money' => (-1*$money), 'before_money' => $before, 'after_money' => $after, 'memo' => $memo,'log_type'=>$arr[$memo],'log_status'=>$log_status,'tran_no'=>$tran_no]);
                    } else { //冻结减少
                        $before_freeze = $user->freeze_money;
                        $after_freeze = function_exists('bcadd') ? bcadd($user->freeze_money, $money, 2) : $user->freeze_money + $money;
                        // 冻结金额不能小于0
                        if ($after_freeze<0) {
                            Db::rollback();
                            return false;
                        }
                        //更新会员信息
                        $res = $user->save(['freeze_money' => $after_freeze]);
                        //写入日志
                        UserMoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before_freeze_money' => $before_freeze, 'after_freeze_money' => $after_freeze, 'memo' => $memo,'log_type'=>$arr[$memo],'log_status'=>$log_status,'tran_no'=>$tran_no]);
                    }
                } else {
                    $before = $user->money;
                    $after = function_exists('bcadd') ? bcadd($user->money, $money, 2) : $user->money + $money;
                    //更新会员信息
                    $res = $user->save(['money' => $after]);
                    //写入日志
                    UserMoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before_money' => $before, 'after_money' => $after, 'memo' => $memo,'log_type'=>$arr[$memo],'log_status'=>$log_status,'tran_no'=>$tran_no]);
                }
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            return false;
            throw new \Exception($e, 1);
            
        }
    }

    /**
     * 变更会员吃豆
     * @param int    $beans   吃豆
     * @param int    $user_id 会员ID
     * @param string $log_desc    备注
     * @param string $tran_no 编号
     */
    public static function beans($beans, $user_id, $log_desc, $tran_no, $log_status = 1)
    {
        $arr = ['下单返豆'=>1,'异常订单收回吃豆'=>5,'抽奖获得'=>6,'吃豆提现'=>2,'下级返利'=>3,'提现驳回'=>4,'管理员操作'=>7,'拉新薅羊毛'=>8,'修改渠道结算金额'=>9];
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $beans != 0) {
                $before = $user->beans;
                $after = function_exists('bcadd') ? bcadd($user->beans, $beans, 2) : $user->beans + $beans;
                //更新会员信息
                $res = $user->save(['beans' => $after]);
                //写入日志
                $logs = UserBeansLog::create(['user_id' => $user_id, 'beans' => $beans, 'before_beans' => $before, 'after_beans' => $after, 'log_desc' => $log_desc,'log_type'=>$arr[$log_desc],'log_status'=>$log_status,'tran_no'=>$tran_no]);
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            throw new \Exception($e, 1);
            
        }
    }


    public static function score($score, $user_id, $memo)
    {
        $arr = ['注册赠送'=>1,'下单获得'=>2,'邀请获得'=>3];
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            $level = $user->level;
            if ($user && $score != 0) {
                switch ($user->level) {
                    case 0:
                        $vip = ['邀请有效成员数量'=>0,'完成订单数量'=>0];
                        break;
                    case 1:
                        $vip = Config::getConfigs('growth_conditions2');
                        break;
                    case 2:
                        $vip = Config::getConfigs('growth_conditions3');
                        break;
                    case 3:
                        $vip = Config::getConfigs('growth_conditions4');
                        break;
                    case 4:
                        $vip = Config::getConfigs('growth_conditions5');
                        break;
                }
                $order_num = UserScoreLog::where(['user_id'=>$user_id,'log_type'=>2,'level'=>['>=',$user->level]])->count();
                $invite_num = UserScoreLog::where(['user_id'=>$user_id,'log_type'=>3,'level'=>['>=',$user->level]])->count();
                if ($arr[$memo]==2) {
                    $order_num = $order_num+1;
                } elseif ($arr[$memo]==3) {
                    $invite_num = $invite_num+1;
                }
                // 满足升级条件
                if ($user->level && $order_num>=$vip['完成订单数量'] && $invite_num>=$vip['邀请有效成员数量']) {
                    $before = $user->score;
                    $after = $user->score + $score;
                    // $level+1是为了作为用户等级没有更新时区别已经更新等级的log
                    UserScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before_score' => $before, 'after_score' => $after, 'log_desc' => $memo, 'log_type' => $arr[$memo], 'level'=>$level+1]);
                    $ids = [];
                    $order_list = UserScoreLog::where(['user_id'=>$user_id,'log_type'=>2,'level'=>['>=',$user->level]])->order('id ASC')->limit($vip['完成订单数量'])->field('id')->select();
                    foreach ($order_list as $key => $value) {
                        $ids[] = $value['id'];
                    }
                    $invite_list = UserScoreLog::where(['user_id'=>$user_id,'log_type'=>3,'level'=>['>=',$user->level]])->order('id ASC')->limit($vip['邀请有效成员数量'])->field('id')->select();
                    foreach ($invite_list as $key => $values) {
                        $ids[] = $values['id'];
                    }
                    UserScoreLog::where(['id'=>['in',$ids]])->update(['level'=>$level,'update_dt'=>date('Y-m-d H:i:s')]);
                    //更新会员信息
                    $level = $level+1;
                } else {
                    $before = $user->score;
                    $after = $user->score + $score;
                    // $level+1是为了作为用户等级没有更新时区别已经更新等级的log
                    UserScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before_score' => $before, 'after_score' => $after, 'log_desc' => $memo, 'log_type' => $arr[$memo], 'level'=>$level+1]);
                }
                // 此处有时间再调整
                $user->save([
                    'score' => $after, 
                    'level' => $level
                ]);
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            return false;
        }
    }

    /**
     * 变更会员积分
     * @param int    $score   积分
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     */
    public static function score1($score, $user_id, $memo)
    {
        $arr = ['注册赠送'=>1,'下单获得'=>2,'邀请获得'=>3];
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $score != 0) {
                $list = UserScoreLog::nextlevel($user_id, $user->score, $user->level, $arr[$memo], $score);
                //写入日志，当前获得的积分计入旧的等级里,level为实际level
                $vip[1] = ['邀请有效成员数量'=>0,'完成订单数量'=>0];
                $vip[2] = Config::getConfigs('growth_conditions2');
                $vip[3] = Config::getConfigs('growth_conditions3');
                $vip[4] = Config::getConfigs('growth_conditions4');
                $vip[5] = Config::getConfigs('growth_conditions5');
                if ($arr[$memo]==2) {
                    $order_num = UserScoreLog::where(['user_id'=>$user_id,'log_type'=>$arr[$memo]])->count();
                    if ($order_num<$vip[2]['完成订单数量']) {
                        $level = 1;
                    } elseif ($order_num<$vip[2]['完成订单数量']+$vip[3]['完成订单数量']) {
                        $level = 2;
                    } elseif ($order_num<$vip[2]['完成订单数量']+$vip[3]['完成订单数量']+$vip[4]['完成订单数量']) {
                        $level = 3;
                    } elseif ($order_num<$vip[2]['完成订单数量']+$vip[3]['完成订单数量']+$vip[4]['完成订单数量']+$vip[5]['完成订单数量']) {
                        $level = 4;
                    } else {
                        $level = 5;
                    }
                } else {
                    $order_num = UserScoreLog::where(['user_id'=>$user_id,'log_type'=>$arr[$memo]])->count();
                    if ($order_num<$vip[2]['邀请有效成员数量']) {
                        $level = 1;
                    } elseif ($order_num<$vip[2]['邀请有效成员数量']+$vip[3]['邀请有效成员数量']) {
                        $level = 2;
                    } elseif ($order_num<$vip[2]['邀请有效成员数量']+$vip[3]['邀请有效成员数量']+$vip[4]['邀请有效成员数量']) {
                        $level = 3;
                    } elseif ($order_num<$vip[2]['邀请有效成员数量']+$vip[3]['邀请有效成员数量']+$vip[4]['邀请有效成员数量']+$vip[5]['邀请有效成员数量']) {
                        $level = 4;
                    } else {
                        $level = 5;
                    }
                }
                //更新会员信息
                $before = $user->score;
                $after = $user->score + $list['score'];
                // 此处有时间再调整
                $user->save([
                    'score' => intval(UserScoreLog::where(['user_id'=>$user_id,'log_type'=>2,'level'=>['<=',$list['level']]])->count())*config('order_score')+intval(UserScoreLog::where(['user_id'=>$user_id,'log_type'=>3,'level'=>['<=',$list['level']]])->count())*config('invite_score'), 
                    'level' => $list['level']
                ]);
                UserScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before_score' => $before, 'after_score' => $after, 'log_desc' => $memo, 'log_type' => $arr[$memo], 'level'=>$level]);
                $user->save([
                    'score' => intval(UserScoreLog::where(['user_id'=>$user_id,'log_type'=>2,'level'=>['<=',$list['level']]])->count())*config('order_score')+intval(UserScoreLog::where(['user_id'=>$user_id,'log_type'=>3,'level'=>['<=',$list['level']]])->count())*config('invite_score'), 
                    'level' => $list['level']
                ]);
                // 此处有时间再调整
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            return false;
        }
    }
}
